/**
 * 文件名：@AfwHandlerMapping.java <br/>
 * 包名：cn.efunbox.afw.web.mvc.springmvc <br/>
 * 项目名：afw-mvc-web <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.web.mvc.springmvc;

import java.lang.reflect.Method;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import cn.efunbox.afw.core.exception.AfwRuntimeException;
import cn.efunbox.afw.core.resolver.HandlerInfoResolver;

/**
 * 类名：AfwHandlerMapping  <br />
 *
 * 功能：对spring提供的org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping进行扩展
 * 
 * 		实现通过注解添加对模板的相关处理
 *
 * @author xtwin <br />
 * 创建时间：2015年12月1日 下午5:12:51  <br />
 * @version 2015年12月1日
 */
public class AfwHandlerMapping extends RequestMappingHandlerMapping {
	
	// 日志记录器
	private static final Log logger = LogFactory.getLog(AfwHandlerMapping.class);
	
	// 处理器信息解析器
	private HandlerInfoResolver handlerInfoResolver;
	
//	// 方法参数名称发现器
	private ParameterNameDiscoverer parameterNameDiscoverer;
	
	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2015年12月9日 下午2:02:15<br/>
	 * 
	 * @param handler
	 * @param request
	 * @return <br/>
	 * @see org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerExecutionChain(java.lang.Object, javax.servlet.http.HttpServletRequest)
	 */
	@Override
	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
		
		try {
			List<?> stacks = handlerInfoResolver.resolve(handler).getTemplator().getStack();
			if (null != stacks && stacks.size() > 0) {
				for (Object interceptor : stacks) {
					chain.addInterceptor((HandlerInterceptor) interceptor);
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			
			throw new AfwRuntimeException(e.getMessage());
		}
		
		return chain;
	}
	
	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2015年12月9日 下午2:01:21<br/>
	 * 
	 * @param handler
	 * @param method
	 * @return <br/>
	 * @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#createHandlerMethod(java.lang.Object, java.lang.reflect.Method)
	 */
	@Override
	protected HandlerMethod createHandlerMethod(Object handler, Method method) {
		HandlerMethod handlerMethod = super.createHandlerMethod(handler, method);
		
		try {
			// 注册处理器
			handlerInfoResolver.registe(handlerMethod);
		} catch (Exception e) {
			throw new AfwRuntimeException("handlerInfo.resolve.error : " + e.getMessage());
		}
		
		// 对方法参数做初始化处理
		for (MethodParameter parameter : handlerMethod.getMethodParameters()) {
			parameter.initParameterNameDiscovery(parameterNameDiscoverer);
		}
		
		return handlerMethod;
	}

	/**
	 * @version 2015年12月9日-下午2:03:14
	 */
	public void setHandlerInfoResolver(HandlerInfoResolver handlerInfoResolver) {
		this.handlerInfoResolver = handlerInfoResolver;
	}

	/**
	 * @version 2015年12月9日-下午2:03:45
	 */
	public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
		this.parameterNameDiscoverer = parameterNameDiscoverer;
	}
	
//	// 模板解析器
//	private Resolver<Templator> templatorResolver;
//
//	// 默认结果类型
//	private String resultType;
//	
//	// 方法参数名称发现器
//	private ParameterNameDiscoverer parameterNameDiscoverer;
//	
//	// 拦截器栈映射
//	//private Map<String, HandlerInterceptor[]> interceptors = Collections.emptyMap();
//	// 拦截器解析器
//	//private Resolver<HandlerInterceptor[]> interceptorsResolver;
//	
//	/**
//	 * 功能: <br/>
//	 * 
//	 * 重写：xtwin <br/>
//	 * 
//	 * @version ：2015年12月1日 下午5:13:16<br/>
//	 * 
//	 * @param handler
//	 * @param request
//	 * @return <br/>
//	 * @see org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerExecutionChain(java.lang.Object, javax.servlet.http.HttpServletRequest)
//	 */
//	@Override
//	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//		HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
//		
//		if (handler instanceof AfwHandlerMethod) {
//			// 处理template注解
//			//Template template = ((HandlerMethod) handler).getMethod().getAnnotation(Template.class);
//			
//			// 获取模板名称
//			/*String name = null;
//			if (null != template) {
//				// 取出配置的模板名称
//				name = StringUtil.emptyAdjust(template.name());
//			}*/
//			
//			// 解析出模板
//			try {
//				//Templator templator = templatorResolver.resolve(name);
//				
//				// 取得栈名称
//				//String stackName = templator.getStackName();
//				
//				// 添加拦截器
//				//chain.addInterceptors(interceptors.get(stackName));
//				//chain.addInterceptors(interceptorsResolver.resolve(templator.getStackName()));
//				List<?> stacks = ((AfwHandlerMethod) handler).getTemplator().getStack();
//				if (null != stacks && stacks.size() > 0) {
//					for (Object interceptor : stacks) {
//						chain.addInterceptor((HandlerInterceptor) interceptor);
//					}
//				}
//			} catch (Exception e) {
//				logger.error(e.getMessage(), e);
//				
//				throw new AfwRuntimeException(e.getMessage());
//			}
//		}
//		
//		return chain;
//	}
//	
//	/**
//	 * 功能: <br/>
//	 * 
//	 * 重写：xtwin <br/>
//	 * 
//	 * @version ：2015年12月8日 下午5:03:59<br/>
//	 * 
//	 * @param request
//	 * @return
//	 * @throws Exception <br/>
//	 * @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerInternal(javax.servlet.http.HttpServletRequest)
//	 */
//	@Override
//	protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
//		HandlerMethod handlerMethod = super.getHandlerInternal(request);
//		
//		return handlerMethod;
//	}
//	
//	/**
//	 * 功能: <br/>
//	 * 
//	 * 重写：xtwin <br/>
//	 * 
//	 * @version ：2015年12月2日 下午6:00:31<br/>
//	 * 
//	 * @param handler
//	 * @param method
//	 * @return <br/>
//	 * @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#createHandlerMethod(java.lang.Object, java.lang.reflect.Method)
//	 */
//	@Override
//	protected HandlerMethod createHandlerMethod(Object handler, Method method) {
//		
//		// 创建handlerMethod
//		AfwHandlerMethod handlerMethod;
//		if (handler instanceof String) {
//			handlerMethod = new AfwHandlerMethod((String) handler, getApplicationContext(), method);
//		} else {
//			handlerMethod = new AfwHandlerMethod(handler, method);
//		}
//		
//		// 做相关扩展处理
//		try {
//			// 模板处理
//			handlerMethod.setTemplator(resolveTemplator(handlerMethod, method));
//			
//			// 前置执行器处理
//			handlerMethod.setPreInvokers(resolvePreInvoker(handlerMethod, method));
//			
//			// 后置执行器处理
//			handlerMethod.setPostInvokers(resolvePostInvoker(handlerMethod, method));
//			
//			// 默认结果类型
//			handlerMethod.setResultType(resolveResultType(handlerMethod, method));
//			
//			// 取得提取字段信息
//			handlerMethod.setExtract(resolveExtract(handlerMethod, method));
//			
//			// 数据绑定配置
//			handlerMethod.setBinds(resolveBind(handlerMethod, method));
//			
//			// 初始化参数信息
//			for (MethodParameter parameter : handlerMethod.getMethodParameters()) {
//				// 初始化参数名称发现器
//				parameter.initParameterNameDiscovery(parameterNameDiscoverer);
//			}
//		} catch (Exception e) {
//			logger.error(e.getMessage(), e);
//			
//			throw new AfwRuntimeException("create handler method error : " + e.getMessage());
//		}
//		
//		return handlerMethod;
//	}
//
//	/**
//	 * 功能： <br/>
//	 *
//	 * @author xtwin <br/>
//	 * @version 2015年12月4日 下午2:00:58 <br/>
//	 */
//	protected Bind[] resolveBind(AfwHandlerMethod handlerMethod, Method method) {
//		return method.getAnnotationsByType(Bind.class);
//	}
//
//	/**
//	 * 功能： <br/>
//	 *
//	 * @author xtwin <br/>
//	 * @version 2015年12月3日 下午5:38:53 <br/>
//	 */
//	protected String[] resolveExtract(AfwHandlerMethod handlerMethod, Method method) {
//		Extract extract = handlerMethod.getMethod().getAnnotation(Extract.class);
//		
//		return null != extract ? extract.value() : null;
//	}
//
//	/**
//	 * 功能：解析默认结果类型 <br/>
//	 *
//	 * @author xtwin <br/>
//	 * @version 2015年12月3日 下午4:58:40 <br/>
//	 */
//	protected String resolveResultType(AfwHandlerMethod handlerMethod, Method method) {
//		String resultType = handlerMethod.getTemplator().getResultType();
//		
//		if (null == resultType) {
//			resultType = this.resultType;
//		}
//		
//		return resultType;
//	}
//
//	/**
//	 * 功能：解析当前模板 <br/>
//	 *
//	 * @author xtwin <br/>
//	 * @version 2015年12月3日 下午4:35:20 <br/>
//	 */
//	protected Templator resolveTemplator(AfwHandlerMethod handlerMethod, Method method) throws Exception {
//		// 处理template注解
//		Template template = handlerMethod.getMethod().getAnnotation(Template.class);
//		
//		// 获取模板名称
//		String name = null;
//		if (null != template) {
//			// 取出配置的模板名称
//			name = StringUtil.emptyAdjust(template.name());
//		}
//		
//		// 解析出模板
//		return templatorResolver.resolve(name);
//	}
//
//	/**
//	 * 
//	 * 功能：解析出前置执行器 <br/>
//	 *
//	 * @author xtwin <br/>
//	 * @version 2015年12月3日 下午1:55:11 <br/>
//	 */
//	protected Invoker[] resolvePreInvoker(Object handler, Method method) throws Exception {
//		PreAction[] pas = method.getAnnotationsByType(PreAction.class);
//		
//		if (null != pas && pas.length > 0) {
//			List<Invoker> invokers = new ArrayList<Invoker>();
//			
//			ApplicationContext ctx = getApplicationContext();
//			
//			for (PreAction pa : pas) {
//				resolveInvoker(invokers, ctx, pa.value(), pa.name(), pa.type(), pa.method(), handler, method);
//			}
//			
//			// 转为数组返回
//			return invokers.toArray(new Invoker[invokers.size()]);
//		}
//		
//		return null;
//	}
//	
//	/**
//	 * 
//	 * 功能：解析出后置拦截器 <br/>
//	 *
//	 * @author xtwin <br/>
//	 * @version 2015年12月3日 下午1:56:34 <br/>
//	 */
//	protected Invoker[] resolvePostInvoker(Object handler, Method method) throws Exception {
//		PostAction[] pas = method.getAnnotationsByType(PostAction.class);
//		
//		if (null != pas && pas.length > 0) {
//			List<Invoker> invokers = new ArrayList<Invoker>();
//			
//			ApplicationContext ctx = getApplicationContext();
//			
//			for (PostAction pa : pas) {
//				resolveInvoker(invokers, ctx, pa.value(), pa.name(), pa.type(), pa.method(), handler, method);
//			}
//			
//			// 转为数组返回
//			return invokers.toArray(new Invoker[invokers.size()]);
//		}
//		
//		return null;
//	}
//	
//	/**
//	 * 
//	 * 功能： <br/>
//	 *
//	 * @author xtwin <br/>
//	 * @version 2015年12月3日 下午2:28:08 <br/>
//	 */
//	protected void resolveInvoker(List<Invoker> invokers, ApplicationContext ctx, String[] exps, String beanName, Class<?> type, String mname, Object handler, Method method) throws Exception {
//		Object bean = null;
//		
//		// 优先按name方式处理
//		if (! StringUtil.isEmpty(beanName)) {
//			bean = ctx.getBean(beanName);
//		} else if (Void.class != type) {
//			bean = ctx.getBean(type);
//		}
//		
//		if (null != bean) {
//			invokers.add(new ReflectMethodInvoker(bean, bean.getClass().getMethod(StringUtil.isEmpty(mname) ? "execute" : mname, Context.class)));
//		} else {
//			if (null == exps || exps.length == 0) {
//				throw new AfwRuntimeException("illegal.preAction.definition.on.method : " + method);
//			}
//			
//			/**
//			 * 在表达式中可以使用！指定方法名，使用c:开头指明当前使用的是类名，如：
//			 * 	testAction
//			 * 		代表bean id为testAction的bean的execute方法
//			 * 	c:testAction
//			 * 		代表bean的类全名为testAction的execute方法
//			 * 	testAction!update
//			 * 		代表bean id为testAction的bean的update方法
//			 * 	c:testAction!update
//			 * 		代表bean的类全名为testAction的update方法
//			 */
//			for (String exp : exps) {
//				
//				String _mname = "execute";
//				
//				int index = exp.indexOf('!');
//				
//				if (index != -1) {
//					_mname = exp.substring(index + 1);
//					
//					exp = exp.substring(0, index);
//				}
//				
//				if (exp.startsWith("c:")) {
//					// 类名
//					bean = ctx.getBean(Class.forName(exp.substring(2)));
//				}
//				
//				invokers.add(new ReflectMethodInvoker(bean, bean.getClass().getMethod(_mname, Context.class)));
//			}
//		}
//	}
//
//	/**
//	 * @version 2015年12月2日-下午4:42:13
//	 */
//	public void setTemplatorResolver(Resolver<Templator> templatorResolver) {
//		this.templatorResolver = templatorResolver;
//	}
//
//	/**
//	 * @version 2015年12月8日-下午2:15:05
//	 */
//	public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
//		this.parameterNameDiscoverer = parameterNameDiscoverer;
//	}
//
//	/**
//	 * @version 2015年12月3日-下午5:00:34
//	 */
//	public void setResultType(String resultType) {
//		this.resultType = resultType;
//	}
//	/**
//	 * @version 2015年12月2日-下午4:42:13
//	 */
//	/*public void setInterceptors(Map<String, HandlerInterceptor[]> interceptors) {
//		this.interceptors = interceptors;
//	}*/
}